#
#   Google.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Salvatore S. Gionfriddo
#   Contributors: Nicholas F. Hoover
#   Created: 2007.11.18
#   Last Modified: 2007.11.18
#

import pygame
from GameObject import GameObject
from Animation import Animation
from Hero import Hero
from Flame import Flame, Gas

class Google(Hero):
    """ A playable character with hunger, heartburn, and gas stats the allow him to breathe fire and fart noxious gas to destroy his enemies.
    """
    HERO_NAME = 'Google'
#########
# STATS #
#########
    MAX_HUNGER = 100
    MIN_HUNGER = 0
    START_HUNGER = 40

    HUNGER_DAMAGE_PER_TICK = 2

    STARVATION_DAMAGE = 4

    STARVATION_MIN = 0
    STARVATION_MAX = 20
    
    HEARTBURN_MIN  = 80
    HEARTBURN_END  = 70
    FLAME_COST = 10

    MIN_GAS = 0
    MAX_GAS = 100
    GAS_COST = 15


##############
# ANIMATIONS #
##############
    PUNCH = Hero.ATTACK1
    KICK  = Hero.ATTACK2
    FLAME = Hero.SPECIAL1
    GAS   = Hero.SPECIAL2

    ###############
    # FRAME_TICKS #
    ###############
    IDLE_FRAME_TICKS   = 4
    WALK_FRAME_TICKS   = 2
    PUNCH_FRAME_TICKS  = [1,1,1] #3  updates for 2 kills .75 efficiency
    KICK_FRAME_TICKS   = [1,2,3,2,1] #9 updates for 7 kills .77 efficiency
    EAT_FRAME_TICKS    = [1,1,2,2,2,1]
    FLAME_FRAME_TICKS  = [2,3,2,5]
    GAS_FRAME_TICKS    = 2
    PICKUP_FRAME_TICKS = [1,1,2,2,1]
    USE_FRAME_TICKS    = 1
    
    ##############
    # KEY FRAMES #
    ##############
    PUNCH_KEY_FRAME  = 1
    KICK_KEY_FRAME   = 2
    EAT_KEY_FRAME    = 3
    FLAME_KEY_FRAME  = 3
    GAS_KEY_FRAME    = 2
    PICKUP_KEY_FRAME = 3
    USE_KEY_FRAME    = 1

    #########################
    # ATTACK COLLISION DATA #
    #########################
    PUNCH_RECT  = pygame.Rect((10,50),(20,10))
    KICK_RECT   = pygame.Rect((15,60),(15,20))
    EAT_RECT    = pygame.Rect((10,80),(12,12))
#    PICKUP_RECT = pygame.Rect(EAT_RECT)
    
    ###################
    # ANIMATION TABLE #
    ###################
    ANIMATION_TABLE = [
        (Hero.IDLE,      'Google_Idle',     IDLE_FRAME_TICKS,  Animation.NO_KEY_FRAME),
        (Hero.WALK_UP,   'Google_WalkUp',   WALK_FRAME_TICKS,  Animation.NO_KEY_FRAME),
        (Hero.WALK_DOWN, 'Google_WalkDown', WALK_FRAME_TICKS,  Animation.NO_KEY_FRAME),
        (Hero.WALK_SIDE, 'Google_WalkSide', WALK_FRAME_TICKS,  Animation.NO_KEY_FRAME),
        (PUNCH,          'Google_Punch',    PUNCH_FRAME_TICKS, PUNCH_KEY_FRAME),
        (KICK,           'Google_Kick',     KICK_FRAME_TICKS,  KICK_KEY_FRAME),
        (FLAME,          'Google_Flame',    FLAME_FRAME_TICKS, FLAME_KEY_FRAME),
        (GAS,            'Google_Gas',      GAS_FRAME_TICKS,   GAS_KEY_FRAME),
        (Hero.EAT,       'Google_Eat',      EAT_FRAME_TICKS,   EAT_KEY_FRAME),
        (Hero.PICKUP,    'Google_Pickup',   PICKUP_FRAME_TICKS,PICKUP_KEY_FRAME),
        (Hero.USE,       'Google_Use',      USE_FRAME_TICKS,   USE_KEY_FRAME),
        ]

    #############
    # MOVEMENTS #
    #############
    MOVEMENTS = [(0,0),   #IDLE
                 (0,-12), #WALK_UP
                 (0,12),  #WALK_DOWN
                 (12,0),  #WALK_SIDE
                 (0,0),   #PUNCH
                 (0,0),   #KICK
                 (0,0),   #EAT
                 (0,0),   #FLAME
                 (0,0),   #GAS
                 (0,0),   #PICKUP
                 (0,0),   #USE
                 ]

###########
# ATTACKS #    
###########
    PUNCH_DAMAGE = 200  #Kill 2 basic kids
    KICK_DAMAGE  = 700  #Kill 7 basic kids
    FLAME_DAMAGE = 2000 #Kill 20 basic kids per animation frame
    GAS_DAMAGE = 1000

    ATTACK1_DAMAGE  = PUNCH_DAMAGE
    ATTACK2_DAMAGE  = KICK_DAMAGE
    SPECIAL1_DAMAGE = FLAME_DAMAGE
    SPECIAL2_DAMAGE = GAS_DAMAGE
    
########
# MISC #
########
    DEFAULT_POSITION = (300,300)
    RECT_SIZE = (60,100)

    COLLISION_RECT_SIZE = (0,0)
    COLLISION_RECT_POSITION = (20,95)
    

#############
# FUNCTIONS #
#############
    def __init__(self):
        Hero.__init__(self)
        self.statusFunctions.append(self.updateHungerStatus)
        self.reset()
        
    def reset(self):
        Hero.reset(self)
        self.hunger = Google.START_HUNGER
        self.heartBurn = False
        self.gas = Google.MIN_GAS


    def updateHungerStatus(self):
        self.decHunger(self.HUNGER_DAMAGE_PER_TICK)
        if self.isStarving():
            self.decHealth(self.STARVATION_DAMAGE)
        elif self.hunger >= self.HEARTBURN_MIN:
            self.setHeartBurn(True)
        elif self.hunger < self.HEARTBURN_END:
            self.setHeartBurn(False)
    

#########
# STATS #
#########
    def incHunger(self,amount):
        self.hunger += amount
        if self.hunger > self.MAX_HUNGER:
            self.hunger = self.MAX_HUNGER

    def decHunger(self,amount):
        prevHunger = self.hunger
        self.hunger -= amount
        if self.hunger < self.MIN_HUNGER: self.hunger = self.MIN_HUNGER

        if prevHunger > self.HEARTBURN_END and self.hunger < self.HEARTBURN_END:
            self.playSound('EG_Hungry')
        elif prevHunger > self.STARVATION_MAX and self.isStarving():
            self.playSound('EG_Starving')

    
    def incHealth(self, amount):
        Hero.incHealth(self, amount)
    def decHealth(self, amount):
        Hero.decHealth(self,amount)
        pass

    def setHeartBurn(self, status):
        if not self.heartBurn and status:
            self.playSound('EG_Heartburn')
        self.heartBurn = status

    def incGas(self, amount):
        self.gas += amount
        if self.gas > self.MAX_GAS: self.gas = self.MAX_GAS

    def decGas(self, amount):
        self.gas -= amount
        if self.gas < self.MIN_GAS: self.gas = self.MIN_GAS
        
    def getStats(self):
        return (self.health, self.hunger, self.heartBurn, self.gas, self.speed_bonus, self.regen_bonus, self.toughness_bonus)
    
    def isStarving(self):
        return self.hunger >= self.STARVATION_MIN and self.hunger <= self.STARVATION_MAX

    def isSatiated(self):
        return self.hunger == self.MAX_HUNGER


    def flame(self):
        if self.canAct() and self.heartBurn:
            self.setAnimation(Google.FLAME)
            self.decHunger(Google.FLAME_COST)
            self.playSound('EG_Flame')
            
    def gasAttack(self):
        if self.canAct() and self.gas >= Google.GAS_COST:
            self.setAnimation(Google.GAS)
            self.decGas(Google.GAS_COST)
            self.playSound('Flame')
                

    def createAttack1Sprite(self):
        punchSprite = pygame.sprite.Sprite()
        punchSprite.rect = pygame.Rect(Google.PUNCH_RECT)
        punchSprite.rect.top += self.rect.top
        if self.facing == Google.RIGHT:
            punchSprite.rect.left += self.rect.centerx
        else:
            punchSprite.rect.left = self.rect.centerx - Google.PUNCH_RECT.left - Google.PUNCH_RECT.width
        return punchSprite

    def createAttack2Sprite(self):
        kickSprite = pygame.sprite.Sprite()
        kickSprite.rect = pygame.Rect(Google.KICK_RECT)
        kickSprite.rect.top += self.rect.top
        if self.facing == Google.RIGHT:
            kickSprite.rect.left += self.rect.centerx
        else:
            kickSprite.rect.left = self.rect.centerx - Google.KICK_RECT.left - Google.KICK_RECT.width
        return kickSprite

    def createFlameSprite(self):
        flame = Flame()
        if self.facing == Google.RIGHT:
            flame.setPosition((self.rect.centerx + 20, self.rect.top + 30))
        else:
            flame.setPosition((self.rect.centerx - flame.rect.width - 20, self.rect.top + 30))
            flame.facing = Flame.LEFT
        flame.setAnimation(Flame.FLAME)
        return flame


    def createGasSprite(self):
        gas = Gas()
        if self.facing == Google.RIGHT:
            gas.setPosition((self.rect.left - gas.rect.width, self.rect.top + 60))
        else:
            gas.setPosition((self.rect.right, self.rect.top + 60))
            gas.facing = Gas.LEFT
            
        gas.setAnimation(Gas.GAS)
        return gas
            
    def createEatSprite(self):
        eatSprite = pygame.sprite.Sprite()
        eatSprite.rect = pygame.Rect(Google.EAT_RECT)
        eatSprite.rect.top += self.rect.top
        if self.facing == Google.RIGHT:
            eatSprite.rect.left += self.rect.centerx
        else:
            eatSprite.rect.left = self.rect.centerx - Google.EAT_RECT.left - Google.EAT_RECT.width
        return eatSprite


class DeadGoogle(GameObject):
    
    NUM_ANIMATIONS = 1
    DEAD = 0

    LEFT = NUM_ANIMATIONS

    ###################
    # ANIMATION TABLE #
    ###################
    ANIMATION_TABLE = [
        (DEAD,        'EG_Dead', 1, Animation.NO_KEY_FRAME),
        ]

    DEFAULT_ANIMATION = DEAD
    RECT_SIZE = (100, 60)

        

